/**
 * 管理员API路由
 * 提供缓存统计、查看、清除和刷新功能
 * 提供日志管理功能
 */

const express = require('express');
const router = express.Router();
const statsCache = require('../services/statsCache');
const { updateAllCache, updateDatabaseCache } = require('../../scripts/update_stats_cache');
const fs = require('fs');
const path = require('path');
const util = require('util');
const readdir = util.promisify(fs.readdir);
const stat = util.promisify(fs.stat);
const readFile = util.promisify(fs.readFile);

// 基本身份验证中间件
const basicAuth = (req, res, next) => {
  // 从环境变量获取凭据，如果不存在则使用默认值
  const adminUser = process.env.ADMIN_USERNAME || 'admin';
  const adminPassword = process.env.ADMIN_PASSWORD || 'Admin@2025';
  
  // 从请求头获取凭据
  const authHeader = req.headers.authorization;
  if (!authHeader) {
    return res.status(401).json({ error: '需要授权' });
  }
  
  // 解析凭据
  const auth = Buffer.from(authHeader.split(' ')[1], 'base64').toString().split(':');
  const user = auth[0];
  const password = auth[1];
  
  // 验证凭据
  if (user !== adminUser || password !== adminPassword) {
    return res.status(403).json({ error: '凭据无效' });
  }
  
  next();
};

// 获取缓存统计信息
router.get('/cache/stats', basicAuth, async (req, res) => {
  try {
    const stats = await statsCache.getCacheStats();
    
    if (!stats) {
      return res.status(500).json({ error: '获取缓存统计信息失败' });
    }
    
    res.json({
      code: 0,
      data: stats,
      msg: 'success'
    });
  } catch (error) {
    console.error('获取缓存统计信息失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

// 清除指定缓存
router.delete('/cache', basicAuth, async (req, res) => {
  try {
    const { symbol, interval, range } = req.query;
    
    // 清除缓存
    const success = await statsCache.clearCache(symbol, interval, range);
    
    if (!success) {
      return res.status(500).json({ error: '清除缓存失败' });
    }
    
    res.json({
      code: 0,
      data: {
        cleared: true,
        params: { symbol, interval, range }
      },
      msg: 'success'
    });
  } catch (error) {
    console.error('清除缓存失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

// 刷新指定缓存
router.post('/cache/refresh', basicAuth, async (req, res) => {
  try {
    const { symbol, interval, range } = req.body;
    
    // 验证参数
    if (!symbol || !interval || !range) {
      return res.status(400).json({ error: '缺少必要参数' });
    }
    
    // 先清除缓存
    await statsCache.clearCache(symbol, interval, range);
    
    // 重新计算并更新缓存
    const stats = await statsCache.getStats(symbol, interval, range);
    
    res.json({
      code: 0,
      data: {
        refreshed: true,
        stats
      },
      msg: 'success'
    });
  } catch (error) {
    console.error('刷新缓存失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

// 刷新所有缓存
router.post('/cache/refresh-all', basicAuth, async (req, res) => {
  try {
    // 启动后台任务更新所有缓存
    res.json({
      code: 0,
      data: {
        message: '缓存更新任务已启动',
        startTime: new Date().toISOString()
      },
      msg: 'success'
    });
    
    // 异步执行更新任务
    updateAllCache().catch(error => {
      console.error('更新所有缓存失败:', error);
    });
  } catch (error) {
    console.error('启动缓存更新任务失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

// 获取特定缓存内容
router.get('/cache', basicAuth, async (req, res) => {
  try {
    const { symbol, interval, range } = req.query;
    
    // 验证参数
    if (!symbol || !interval || !range) {
      return res.status(400).json({ error: '缺少必要参数' });
    }
    
    // 获取缓存数据
    const stats = await statsCache.getStatsFromCache(symbol, interval, range);
    
    if (!stats) {
      return res.status(404).json({ error: '缓存不存在或已过期' });
    }
    
    res.json({
      code: 0,
      data: stats,
      msg: 'success'
    });
  } catch (error) {
    console.error('获取缓存内容失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

// -------------- 日志管理API ---------------

// 获取日志文件列表
router.get('/logs', basicAuth, async (req, res) => {
  try {
    const { category = 'app' } = req.query;
    
    // 验证类别
    const validCategories = ['app', 'monitor', 'system'];
    if (!validCategories.includes(category)) {
      return res.status(400).json({ 
        code: 400, 
        msg: '无效的日志类别', 
        error: '类别必须是app、monitor或system之一' 
      });
    }
    
    // 确定日志目录
    const logDir = path.join(__dirname, '../../logs', category);
    
    // 如果目录不存在，返回空列表
    if (!fs.existsSync(logDir)) {
      return res.json({
        code: 0,
        data: [],
        msg: 'success'
      });
    }
    
    // 读取目录内容
    const files = await readdir(logDir);
    
    // 获取文件详情
    const fileDetails = await Promise.all(
      files.map(async (file) => {
        const filePath = path.join(logDir, file);
        const fileStat = await stat(filePath);
        
        return {
          name: file,
          path: `${category}/${file}`,
          size: fileStat.size,
          created: fileStat.birthtime,
          modified: fileStat.mtime,
          isError: file.includes('-error')
        };
      })
    );
    
    // 按修改时间排序（最新的在前）
    fileDetails.sort((a, b) => b.modified - a.modified);
    
    res.json({
      code: 0,
      data: fileDetails,
      msg: 'success'
    });
  } catch (error) {
    console.error('获取日志文件列表失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

// 获取特定日志文件内容
router.get('/logs/:category/:file', basicAuth, async (req, res) => {
  try {
    const { category, file } = req.params;
    const { lines = 1000, tail = true } = req.query;
    
    // 验证类别
    const validCategories = ['app', 'monitor', 'system'];
    if (!validCategories.includes(category)) {
      return res.status(400).json({ 
        code: 400, 
        msg: '无效的日志类别', 
        error: '类别必须是app、monitor或system之一' 
      });
    }
    
    // 防止目录遍历攻击
    if (file.includes('..') || file.includes('/')) {
      return res.status(400).json({ 
        code: 400, 
        msg: '无效的文件名', 
        error: '文件名不能包含特殊字符' 
      });
    }
    
    // 确定日志文件路径
    const logFilePath = path.join(__dirname, '../../logs', category, file);
    
    // 检查文件是否存在
    if (!fs.existsSync(logFilePath)) {
      return res.status(404).json({ 
        code: 404, 
        msg: '文件不存在', 
        error: '请求的日志文件不存在' 
      });
    }
    
    // 读取文件内容
    const content = await readFile(logFilePath, 'utf8');
    
    // 分割成行
    const allLines = content.split('\n');
    
    // 根据参数返回指定数量的行
    let result;
    const lineCount = parseInt(lines);
    
    if (tail === 'true' || tail === true) {
      // 返回最后N行
      result = allLines.slice(-lineCount).join('\n');
    } else {
      // 返回前N行
      result = allLines.slice(0, lineCount).join('\n');
    }
    
    res.json({
      code: 0,
      data: {
        content: result,
        totalLines: allLines.length,
        returnedLines: Math.min(lineCount, allLines.length)
      },
      msg: 'success'
    });
  } catch (error) {
    console.error('获取日志文件内容失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

// 获取日志统计信息（按类别、天数、错误率等）
router.get('/logs/stats', basicAuth, async (req, res) => {
  try {
    // 存储结果
    const stats = {
      categories: {},
      totalSize: 0,
      totalFiles: 0,
      errorRate: 0
    };
    
    // 处理每个日志类别
    const categories = ['app', 'monitor', 'system'];
    
    for (const category of categories) {
      const logDir = path.join(__dirname, '../../logs', category);
      
      // 如果目录不存在，跳过
      if (!fs.existsSync(logDir)) {
        stats.categories[category] = { files: 0, size: 0, errorFiles: 0 };
        continue;
      }
      
      // 读取目录内容
      const files = await readdir(logDir);
      
      // 计算统计信息
      let categorySize = 0;
      let errorFiles = 0;
      
      for (const file of files) {
        const filePath = path.join(logDir, file);
        const fileStat = await stat(filePath);
        categorySize += fileStat.size;
        
        if (file.includes('-error')) {
          errorFiles++;
        }
      }
      
      stats.categories[category] = {
        files: files.length,
        size: categorySize,
        errorFiles
      };
      
      stats.totalFiles += files.length;
      stats.totalSize += categorySize;
    }
    
    // 计算总体错误率
    if (stats.totalFiles > 0) {
      let totalErrorFiles = 0;
      Object.values(stats.categories).forEach(cat => {
        totalErrorFiles += cat.errorFiles;
      });
      
      stats.errorRate = totalErrorFiles / stats.totalFiles;
    }
    
    res.json({
      code: 0,
      data: stats,
      msg: 'success'
    });
  } catch (error) {
    console.error('获取日志统计信息失败:', error);
    res.status(500).json({
      code: 500,
      msg: '服务器内部错误',
      error: error.message
    });
  }
});

module.exports = router; 